﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace PACKETPARSERMAX20.CORE
{
    public static class Extentions
    {


        public enum DateInterval
        {
            Second,
            Minute,
            Hour,
            Day,
            Week,
            Month,
            Quarter,
            Year
        }

        public static bool HasAnyFlag(this Enum value, Enum toTest)
        {
            var val = ((IConvertible)value).ToUInt64(null);
            var test = ((IConvertible)toTest).ToUInt64(null);

            return (val & test) != 0;
        }

        public static uint? GetValueTest(this uint? orig_obj, uint? new_obj)
        {
            if (orig_obj == null && new_obj == null)
                return null;

            if (orig_obj == null && new_obj != null)
                return new_obj;

            if (new_obj == null)
                return orig_obj;//test it

            if (orig_obj.Value != new_obj.Value)
                return new_obj;

            return orig_obj;
        }

        public static DateTime Time_T2DateTime(this uint time_t)
        {
            long win32FileTime = 10000000 * (long)time_t + 116444736000000000;
            return DateTime.FromFileTimeUtc(win32FileTime).ToLocalTime();
        }

        public static string GetString(this System.IO.BinaryReader pbr, int pcount)
        {
            char tbBlock;
            StringBuilder tsb = new StringBuilder();
            if (pcount == -1)
            {
                while ((tbBlock = pbr.ReadChar()) != 0)
                    tsb.Append(tbBlock);
            }
            else
            {
                byte[] tChars = new byte[pcount];
                pbr.Read(tChars, 0, pcount);
                for (int i = 0; i < pcount; i++)
                {
                    tbBlock = (char)tChars[i];// pbr.ReadChar();
                    tsb.Append(tbBlock);
                }
            }
            string tVarChar = tsb.ToString();
            return tVarChar;
        }

        public static bool StringCompareUpper(this string stringA, string stringB)
        {
            return (string.Compare(stringA, stringB, true,
                 System.Globalization.CultureInfo.CurrentCulture) == 0);
        }

        public static string StringConcatenate(this string current, string add)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder(current);
            builder.Append(add);
            return builder.ToString();
        }

        public static string PadRight(this string pValue, int pLength, string pCharacterToAdd)
        {
            string tReturnString = "";

            int tLength = pValue.Length;
            if (tLength < pLength)
            {
                tReturnString = pValue.Trim() + new String(pCharacterToAdd[0], pLength - tLength);
            }
            else
            {
                tReturnString = pValue.Trim().Substring(0, pLength);
            }


            return tReturnString;
        }

        public static string PadLeft(this string pValue, int pLength, string pCharacterToAdd)
        {
            int tLength = 0;
            string tReturnString = "";

            tLength = pValue.Length;
            if (tLength < pLength)
            {
                tReturnString = new String(pCharacterToAdd[0], pLength - tLength) + pValue.Trim();
            }
            else
            {
                tReturnString = pValue.Trim().Substring(pValue.Trim().Length - pLength);
            }


            return tReturnString;
        }

        public static DateTime BeginningOfWeek(this DateTime ForWhichDate)
        {
            return ForWhichDate.AddDays(-((int)ForWhichDate.DayOfWeek));
        }

        public static DateTime BeginningOfPreviousWeek(this DateTime ForWhichDate)
        {
            return ForWhichDate.AddDays(-((int)ForWhichDate.DayOfWeek)).AddDays(-6);
        }

        public static DateTime EndOfWeek(this DateTime ForWhichDate)
        {
            return ForWhichDate.AddDays(((int)ForWhichDate.DayOfWeek));
        }

        public static long DateDiff(this DateInterval Interval, System.DateTime StartDate, System.DateTime EndDate)
        {
            long lngDateDiffValue = 0;
            System.TimeSpan TS = new System.TimeSpan(EndDate.Ticks - StartDate.Ticks);
            switch (Interval)
            {
                case DateInterval.Day:
                    lngDateDiffValue = (long)TS.Days; break;
                case DateInterval.Hour:
                    lngDateDiffValue = (long)TS.TotalHours; break;
                case DateInterval.Minute:
                    lngDateDiffValue = (long)TS.TotalMinutes; break;
                case DateInterval.Month:
                    lngDateDiffValue = (long)(TS.Days / 30); break;
                case DateInterval.Quarter:
                    lngDateDiffValue = (long)((TS.Days / 30) / 3); break;
                case DateInterval.Second:
                    lngDateDiffValue = (long)TS.TotalSeconds; break;
                case DateInterval.Week:
                    lngDateDiffValue = (long)(TS.Days / 7); break;
                case DateInterval.Year:
                    lngDateDiffValue = (long)(TS.Days / 365); break;
            }
            return (lngDateDiffValue);
        }

        public static bool IsDate(this object pValue)
        {

            if (IsEmpty(pValue))
            {
                return false;
            }
            else
            {
                DateTime tOutDate;
                return DateTime.TryParse(pValue.ToString().Trim(), System.Globalization.CultureInfo.CurrentCulture, DateTimeStyles.None, out tOutDate);
            }
        }

        public static bool IsEmpty(this object Value)
        {
            bool tIsEmpty = false;
            if (Value == null || string.Empty.Equals(Value) || DBNull.Value.Equals(Value))
            {
                tIsEmpty = true;
            }
            else
            {
                tIsEmpty = Value.ToString().Length == 0;
            }
            return tIsEmpty;
        }

        public static bool IsNumeric(this object pValue)
        {
            if (pValue == null)
            {
                return false;

            }
            else
            {
                double tOutValue;
                return double.TryParse(pValue.ToString().Trim(),
                    System.Globalization.NumberStyles.Any,
                    System.Globalization.CultureInfo.CurrentCulture,
                    out tOutValue);
            }
        }

        public static int Asc(this char pChar)
        {
            //Return the character value of the given character
            return (int)Encoding.ASCII.GetBytes(new char[] { pChar })[0];
        }

        public static string GetStringOrEmpty(this object pValue)
        {
            if (IsEmpty(pValue))
            {
                return "";
            }
            else
            {
                return pValue.ToString();
            }
        }

        public static string GetStringOrEmpty(object pValue, int pMaxLength)
        {

            if (IsEmpty(pValue))
            {
                return "";
            }
            else
            {
                string tString = pValue.ToString();
                if (tString.Length > pMaxLength)
                {
                    return tString.Substring(0, pMaxLength);
                }
                else
                {
                    return tString;
                }
            }
        }

        public static System.DateTime GetDateOrMin(this object pValue)
        {
            if (!IsDate(pValue))
            {
                return System.DateTime.MinValue;
            }
            else
            {
                DateTime tOutDate;
                DateTime.TryParse(pValue.ToString().Trim(), System.Globalization.CultureInfo.CurrentCulture, DateTimeStyles.None, out tOutDate);
                return tOutDate;
            }
        }

        public static long GetLongOrZero(this object pValue)
        {

            long tReturn = 0;
            if (pValue == null)
            {
                return tReturn;

            }
            else
            {
                long.TryParse(pValue.ToString(), out tReturn);
                //Double.TryParse(pValue.ToString(),  System.Globalization.NumberStyles.Integer & NumberStyles.AllowCurrencySymbol  , System.Globalization.CultureInfo.CurrentCulture, out tReturn);
                return tReturn;
            }
        }

        public static float GetFloatOrZero(this object pValue)
        {

            double tReturn = 0;
            if (pValue == null)
            {
                return (float)tReturn;

            }
            else
            {
                Double.TryParse(pValue.ToString(), NumberStyles.Float & NumberStyles.AllowCurrencySymbol, System.Globalization.CultureInfo.CurrentCulture, out tReturn);
                return (float)tReturn;
            }
        }

        public static double GetDoubleOrZero(this object pValue)
        {
            double tReturn = 0;
            if (pValue == null)
            {
                return tReturn;

            }
            else
            {
                Double.TryParse(pValue.ToString(), NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out tReturn);
                return tReturn;
            }
        }

        public static string GetDBString(this string pValue)
        {
            if (IsEmpty(pValue))
            {
                return " NULL ";
            }
            else
            {
                return "'" + pValue.ToString().Replace("'", "''") + "'";
            }
        }

        public static string GetDBString(this string pValue, int pMaxLength)
        {
            if (IsEmpty(pValue))
            {
                return " NULL ";
            }
            else
            {
                string tString = pValue;
                if (tString.Length > pMaxLength)
                {
                    return "'" + tString.Substring(0, pMaxLength).Replace("'", "''") + "'";
                }
                else
                {
                    return "'" + tString.Replace("'", "''") + "'";
                }

            }
        }

        public static string GetDBNumber(this object pValue)
        {
            if (!IsNumeric(pValue.ToString()))
            {
                return " NULL ";
            }
            else
            {

                return pValue.ToString();

            }
        }

        public static string GetDBDate(this object pValue)
        {
            if (pValue.GetDateOrMin() == System.DateTime.MinValue)
            {
                return " NULL ";
            }
            else
            {

                return "'" + pValue.ToString() + "'";

            }
        }

        public static uint GetUIntOrZero(this object pValue)
        {
            if (pValue == DBNull.Value)
                return 0;

            if (pValue == null)
                return 0;

            uint tOut = 0;

            if (uint.TryParse(pValue.ToString(), out tOut))
                return tOut;

            return 0;
        }

        public static int GetIntOrZero(this object pValue)
        {
            if (pValue.IsEmpty())
                return 0;

            int tOut = 0;

            if (int.TryParse(pValue.ToString(), out tOut))
                return tOut;

            return 0;
        }

        public static string MySQLDBString(this System.String value)
        {
            if (value == null || value == "")return "";
            return value.Replace("'", "\\'").Replace("\n", "\\n").Replace("\r","");
        }

        
    }
}
